import re

from fastapi import APIRouter, Depends, Form, Path, Request
from sqlalchemy import select

from core.database import db_session
from core.exception import AlertException
from core.models import Member
from core.template import UserTemplates
from lib.captcha import captcha_widget
from lib.common import StringEncrypt
from lib.mail import mailer
from lib.dependency.dependencies import validate_token

router = APIRouter()
templates = UserTemplates()
templates.env.globals["captcha_widget"] = captcha_widget


@router.get("/formmail/{mb_id}")
async def formmail(
    request: Request,
    db: db_session,
    mb_id: str = Path,
    name: str = None,
    email: str = None
):
    """
    表单邮件表单写作
    """
    config = request.state.config
    login_member = request.state.login_member

    if not config.cf_email_use:
        raise AlertException(status_code=400, detail='在环境设置中 "使用邮件发送"你需要检查发送邮件.\n\n请联系您的经理.')

    if config.cf_formmail_is_member and not login_member:
        raise AlertException(status_code=400, detail="只有成员可用.")

    if login_member and not login_member.mb_open and not request.state.is_super_admin and login_member.mb_id != mb_id:
        raise AlertException(status_code=400, detail='如果您不透露您的信息，您将无法向其他人发送邮件.\n\n信息公开设置可从会员信息修正.')

    if mb_id:
        exists_member = db.scalar(
            select(Member).where(Member.mb_id == mb_id)
        )
        if not exists_member:
            raise AlertException(status_code=400, detail="这是一个不存在的成员.")

        if not exists_member.mb_open and not request.state.is_super_admin:
            raise AlertException(status_code=400, detail="我们没有透露信息。.")

    sendmail_count = request.session.get('ss_sendmail_count', 0) + 1
    if sendmail_count > 3:
        raise AlertException(status_code=400, detail="一次访问后只能发送一定数量的邮件.\n\n请重新登录或访问以继续发送邮件.")

    enc = StringEncrypt()
    decrypted_email = enc.decrypt(email)

    def get_email_address(email):
        matches = re.findall(r"[0-9a-z._-]+@[a-z0-9._-]{4,}", email, re.I)
        return matches[0] if matches else None

    email = get_email_address(decrypted_email)
    if not email:
        raise AlertException(status_code=400, detail="电子邮件不正确.")

    email = enc.encrypt(email)

    if not name:
        name = email

    context = {
        "request": request,
        "member": login_member,
        "to_name": name,
        "to_email": email,
    }

    return templates.TemplateResponse("bbs/formmail.html", context)


@router.post("/formmail_send", dependencies=[Depends(validate_token)])
async def formmail_send(
    request: Request,
    db: db_session,
    email: str = Form(..., alias="to"),
    name: str = Form(None, alias="fnick"),
    fmail: str = Form(..., alias="fmail"),
    subject: str = Form(..., alias="subject"),
    content: str = Form(..., alias="content"),
):
    """
    发送表单邮件
    """
    enc = StringEncrypt()
    decrypted_to_email = enc.decrypt(email)
    # to_emails = decrypted_to_email.split(',') if ',' in decrypted_to_email else [decrypted_to_email]
    # print(to_emails[0], subject, body)
    # mailer(to_emails, subject, body)
    mailer(fmail, decrypted_to_email, subject, content, name)
